package com.chuangjiangx.member.manager.web.web.coupon.controller;


import com.chuangjiangx.commons.BeanUtils;
import com.chuangjiangx.commons.DateUtils;
import com.chuangjiangx.commons.PageUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.commons.response.CamelResponse;
import com.chuangjiangx.commons.response.Response;
import com.chuangjiangx.commons.response.ResponseUtils;
import com.chuangjiangx.member.basic.ddd.dal.dto.StoreList;
import com.chuangjiangx.member.basic.ddd.query.MerchantInfoQuery;
import com.chuangjiangx.member.basic.ddd.query.dto.MerchantInfoDTO;
import com.chuangjiangx.member.coupon.ddd.application.MbrCouponApplication;
import com.chuangjiangx.member.coupon.ddd.application.command.CreateMbrCouponCommand;
import com.chuangjiangx.member.coupon.ddd.application.command.ModifyMbrCouponCommand;
import com.chuangjiangx.member.coupon.ddd.dal.dto.MbrCouponDetail;
import com.chuangjiangx.member.coupon.ddd.dal.dto.MbrCouponList;
import com.chuangjiangx.member.coupon.ddd.dal.dto.MbrHasCouponList;
import com.chuangjiangx.member.coupon.ddd.domain.model.MbrCoupon;
import com.chuangjiangx.member.coupon.ddd.domain.repository.MbrCouponRepository;
import com.chuangjiangx.member.coupon.ddd.domain.repository.MbrHasCouponRepository;
import com.chuangjiangx.member.coupon.ddd.domain.service.CouponDomainService;
import com.chuangjiangx.member.coupon.ddd.query.MbrCouponQuery;
import com.chuangjiangx.member.coupon.ddd.query.condition.MbrCouponListCondition;
import com.chuangjiangx.member.manager.basic.web.controller.BaseController;
import com.chuangjiangx.member.manager.basic.web.interceptor.Login;
import com.chuangjiangx.member.manager.common.CodeUtils;
import com.chuangjiangx.member.manager.common.Constants;
import com.chuangjiangx.member.manager.common.ThreadLocalUser;
import com.chuangjiangx.member.manager.web.web.basic.response.H5LinkDataResponse;
import com.chuangjiangx.member.manager.web.web.coupon.request.CreateCouponRequest;
import com.chuangjiangx.member.manager.web.web.coupon.request.ModifyCouponRequest;
import com.chuangjiangx.member.manager.web.web.coupon.request.SearchCouponListRequest;
import com.chuangjiangx.member.manager.web.web.coupon.response.CouponListResponse;
import com.chuangjiangx.member.manager.web.web.coupon.response.MbrCouponDetailResponse;
import com.sun.jmx.snmp.ThreadContext;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

/**
 * 会员卡卡券
 */
@RestController
@Api(value = "卡券",tags = "卡券")
@RequestMapping(value = "/api/mbr/mbr-coupon", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
public class MbrCouponController extends BaseController {

    private final MbrCouponQuery mbrCouponQuery;
    private final MerchantInfoQuery merchantInfoQuery;
    private final MbrCouponApplication mbrCouponApplication;

    @Autowired
    private CouponDomainService couponDomainService;
    @Autowired
    private MbrCouponRepository mbrCouponRepository;
    @Autowired
    private MbrHasCouponRepository mbrHasCouponRepository;

    @Autowired
    public MbrCouponController(
            MbrCouponQuery mbrCouponQuery,
            MbrCouponApplication mbrCouponApplication,
            MerchantInfoQuery merchantInfoQuery) {
        this.mbrCouponQuery = mbrCouponQuery;
        this.mbrCouponApplication = mbrCouponApplication;
        this.merchantInfoQuery = merchantInfoQuery;
    }

    /**
     * 加载商户下门店
     * @param name 门店名称
     * @return com.chuangjiangx.commons.response.CamelResponse
     * @map data
     * @see StoreList
     */
    @RequestMapping(value = "/store-list-merchant")
    @Login
    public Response listStoreForMerchant(String name,Integer type) {
        ThreadLocalUser token = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        List<StoreList> storeList = mbrCouponQuery.findStoreListByMerchantId(token.getMerchantId(),name);
        //当type==1时,需要包含商户主账号信息
        if(type!=null){
            if(type==1){
                StoreList store = new StoreList();
                store.setId(-1L);
                store.setName("商户主账号");
                storeList.add(store);
            }
        }
        return ResponseUtils.successCamel(storeList);
    }

    /**
     * 加载卡券可使用门店
     * @param couponNumber 卡券编号
     * @param name 门店名称
     * @return com.chuangjiangx.commons.response.CamelResponse
     * @map data
     * @see StoreList
     */

    @RequestMapping(value = "/store-list-mbr-coupon")
    @Login
    public Response listStoreForMbrCoupon(String couponNumber,String name) {
        List<StoreList> storeList = mbrCouponQuery.findStoreListByCouponNumber(couponNumber,name);
        return ResponseUtils.successCamel(storeList);
    }

    private BiConsumer<MbrCouponList,CouponListResponse> consumer = (mbrCoupon, resp) -> {
        Date now = new Date();
        Integer status = now.before(mbrCoupon.getActTimeStart()) ? 0 : now.before(mbrCoupon.getActTimeEnd()) ? 1 : 2;
        resp.setStatus(status);
        resp.setStatusText(status == 0 ? "未开始" : status == 1 ? "进行中" : "已结束");
    };

    /**
     * 商户卡券列表
     *
     * @param request 查询条件
     * @return com.chuangjiangx.commons.response.CamelResponse
     * @map couponList List
     * @map page
     * @see CouponListResponse
     * @see com.chuangjiangx.commons.page.Page
     */
    @RequestMapping(value = "/list-for-merchant")
    @Login
    public Response couponListForMerchant( @RequestBody SearchCouponListRequest request) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        MbrCouponListCondition condition = new MbrCouponListCondition();
        condition.setMerchantId(user.getMerchantId());
        BeanUtils.convertBean(request,condition);
        PageUtils.copyPage(condition,request.getPage());
        if(!ObjectUtils.isEmpty(request.getStatus())){
            List<Integer> statusList = new ArrayList<>(Arrays.asList(request.getStatus()));
            condition.setStatuses(statusList);
        }
        PagingResult<MbrCouponList> result = mbrCouponQuery.findMbrCouponListForMerchant(condition);
        List<CouponListResponse> list = BeanUtils.convertCollection(result.getItems(), CouponListResponse.class,consumer);
        return ResponseUtils.successCamelPage(request.getPage(), result, "couponList", list);
    }

    /**
     * 店长加载卡券列表
     * @param request 参数
     * @return com.chuangjiangx.commons.response.CamelResponse
     * @map couponList List
     * @map page
     * @see CouponListResponse
     * @see com.chuangjiangx.commons.page.Page
     */
    @RequestMapping(value = "/list-for-store")
    @Login
    public Response couponListForStore(@RequestBody SearchCouponListRequest request) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        MbrCouponListCondition condition = new MbrCouponListCondition();
        condition.setMerchantId(user.getMerchantId());
        condition.setStoreId(user.getStoreId());
        BeanUtils.convertBean(request,condition);
        PagingResult<MbrCouponList> result = mbrCouponQuery.findMbrCouponListForStore(condition);
        List<CouponListResponse> list = BeanUtils.convertCollection(result.getItems(), CouponListResponse.class,consumer);
        return ResponseUtils.successCamelPage(request.getPage(), result, "couponList", list);
    }

    /**
     * 商户创建卡券
     *
     * @param createCouponRequest 创建参数
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @RequestMapping(value = "/create",method = RequestMethod.POST)
    @ApiOperation(value = "创建卡券",httpMethod = "POST")
    @Login
    public Response createCoupon(@Validated @RequestBody(required = false) CreateCouponRequest createCouponRequest) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        CreateMbrCouponCommand command = new CreateMbrCouponCommand();
        BeanUtils.convertBean(createCouponRequest,command);
        command.setMerchantId(user.getMerchantId());
        //领取后X天有效，计算有效期区间，后续查询不需要每次计算
        if(command.getValidType() == 0) {
            if (command.getClaimedTime() != null) {
                command.setValidTimeStart(new Date());
                command.setValidTimeEnd(DateUtils.add(new Date(), Long.valueOf(createCouponRequest.getClaimedTime()), ChronoUnit.DAYS));
            }
        }
        MbrCoupon mbrCoupon = mbrCouponApplication.createMbrCoupon(command);
        //同步至第三方避免系统新建也回滚，分开操作
        if(command.getSyncType()!=null){
            String[] syncTypes = command.getSyncType().split(",");
            //1 微信
            if(Arrays.asList(syncTypes).contains("1")){
                MerchantInfoDTO merchantInfoDTO = merchantInfoQuery.searchMerchantInfoForH5(mbrCoupon.getMerchantId().getId());
                mbrCouponApplication.createWxCashCoupon(mbrCoupon.getId(),merchantInfoDTO.getName());
            }
        }
        return (CamelResponse)ResponseUtils.successCamel("couponNumber",mbrCoupon.getCouponNumber());
    }

    /**
     * 商户修改卡券
     *
     * @param modifyCouponRequest 修改参数
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @ApiOperation(value = "修改卡券",httpMethod = "POST")
    @RequestMapping(value = "/update",method = RequestMethod.POST)
    @Login
    public CamelResponse updateCoupon(@Validated @RequestBody ModifyCouponRequest modifyCouponRequest) {
        ModifyMbrCouponCommand command = new ModifyMbrCouponCommand();
        BeanUtils.convertBean(modifyCouponRequest,command);
        MbrCouponDetail infoBefore = mbrCouponQuery.getMbrCouponDetailInfo(modifyCouponRequest.getCouponNumber());
        MbrCoupon mbrCoupon = mbrCouponApplication.updateMbrCoupon(command);
        //同步至第三方避免系统新建也回滚，分开操作
        if(command.getSyncType()!=null){
            String[] syncTypes = command.getSyncType().split(",");
            //1 微信
            if(Arrays.asList(syncTypes).contains("1")){
                //之前同步过微信的走修改 没同步过的走新增
                MerchantInfoDTO merchantInfoDTO = merchantInfoQuery.searchMerchantInfoForH5(mbrCoupon.getMerchantId().getId());
                if(Objects.equals(infoBefore.getWxCardId(),null)||Objects.equals(infoBefore.getWxCardId(),"")){
                    mbrCouponApplication.createWxCashCoupon(mbrCoupon.getId(),merchantInfoDTO.getName());
                }else{
                    mbrCouponApplication.updateWxCashCoupon(mbrCoupon.getId(),merchantInfoDTO.getName());
                }
            }
        }
        return (CamelResponse)ResponseUtils.successCamel();
    }

    /**
     * 卡券详情
     *
     * @param couponNumber 卡券编号
     * @return com.chuangjiangx.commons.response.CamelResponse
     * @see MbrCouponDetailResponse
     */
    @ApiOperation(value = "卡券详情",httpMethod = "GET")
    @RequestMapping(value = "/coupon-detail-info",method = RequestMethod.GET)
    @Login
    public CamelResponse<MbrCouponDetailResponse> couponDetailInfo(@ApiParam(value = "卡券编号" ,required = true) String couponNumber) {
        MbrCouponDetail detailInfo = mbrCouponQuery.getMbrCouponDetailInfo(couponNumber);
        MbrCouponDetailResponse resp = new MbrCouponDetailResponse();
        BeanUtils.convertBean(detailInfo,resp, (detail, res) -> {
            String storeIds = detailInfo.getStoreLists().stream().map(val -> val.getId() + "").collect(Collectors.joining(","));
            res.setStoreIds(storeIds);
            res.setStoreNum(detailInfo.getStoreLists() == null ? 0 : detailInfo.getStoreLists().size());
        });
        if (resp.getStoreNum()!=null&& resp.getStoreNum()==1){
            resp.setOnlyOneStoreName(detailInfo.getStoreLists().get(0).getName());
        }
        if(resp.getValidType() == 1){
            resp.setValidTimeStart(null);
            resp.setValidTimeEnd(null);
        }
        return (CamelResponse<MbrCouponDetailResponse>)ResponseUtils.successCamel(resp);
    }



    /**
     * 修改卡券库存
     * @param couponNumber 卡券编号
     * @param amount 数量
     * @param addOrSub 1-增加 2-减少
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @RequestMapping(value = "/update-inventory")
    @Login
    public Response updateMbrCouponInventory(String couponNumber, Long amount, Integer addOrSub) {
        switch (addOrSub) {
            case 1 :
                //增加库存
                mbrCouponApplication.addMbrCouponInventory(couponNumber,amount);
                break;
            case 2 :
                //减少库存
                mbrCouponApplication.subtractMbrCouponInventory(couponNumber,amount);
                break;
            default:
                throw new IllegalArgumentException();
        }
        return ResponseUtils.successCamel();
    }

    /**
     * 复制卡券
     * @param couponNumber 卡券编号
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @RequestMapping(value = "/copy-coupon")
    @Login
    public Response copyMbrCoupon(String couponNumber) {
        mbrCouponApplication.copyMbrCoupon(couponNumber);
        return ResponseUtils.successCamel();
    }

    /**
     * 结束卡券活动
     * @param couponNumber 卡券id
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @RequestMapping(value = "/finish-activity")
    @Login
    public Response finishActivity(String couponNumber) {
        mbrCouponApplication.finishActivity(couponNumber);
        return ResponseUtils.successCamel();
    }

    /**
     * 删除卡券活动
     * @param couponNumber 卡券编号
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @RequestMapping(value = "/del-coupon")
    @Login
    public Response delCoupon(String couponNumber) {
        mbrCouponApplication.deleteMbrCoupon(couponNumber);
        return ResponseUtils.successCamel();
    }

    /**
     * 卡卷推广二维码，扫码进入H5领劵详情点击领取
     * @param couponNumber 卡券编号
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @RequestMapping(value = "/push-coupon")
    @Login
    public Response pushCoupon(String couponNumber) {
        String pushCouponUrl =  mbrCouponApplication.pushMbrCoupon(couponNumber);
        String qrcode = CodeUtils.generateQrCode(pushCouponUrl);
        H5LinkDataResponse response = new H5LinkDataResponse();
        response.setQrcode(qrcode);
        response.setUrl(pushCouponUrl);
        return ResponseUtils.successCamel(response);
    }


    /**
     * 加载会员可用的卡券
     * @param memberId 会员id
     * @return com.chuangjiangx.commons.response.CamelResponse
     */
    @RequestMapping(value = "/mbr-coupon/list-mbr-has-coupon")
    @Login
    public Response mbrHasCouponList(Long memberId) {
        List<MbrHasCouponList> mbrHasCouponList = mbrCouponQuery.findMbrHasCouponList(memberId, 0);
        return ResponseUtils.successCamel(mbrHasCouponList);
    }
}
